#include <iostream>
using namespace std;

int main01(int argc, char const *argv[]){
        double dpi = 3.1415926;
        
        int num1 = (int)dpi; //c类型转换
        int num2 = static_cast<int>(dpi); //静态类型转换 编译时c++编译器会做类型检查
        int num3 = dpi; //c语言中隐式类型转换的地方 均可使用 static_cast<>() 进行转换

        //char* ==> int *
        char *p1 = "hello aaa";
        int *p2 = NULL;
        //p2 = static_cast<int *> p1; //使用static_cast<>()编译器编译时，会做类型检查 若有错误 提示错误 编译不通过
        
        p2 = reinterpret_cast<int *>(p1); //若不同类型之间，进行强制类型转换，用 reinterpret_cast<>()进行重新编译解释
        cout<<"p1: "<<p1<<endl; //%s
        cout<<"p2: "<<p2<<endl; //%d

        //总结：通过 reinterpret_cast<>() 和 static_cast<>() 把c语言强制类型转换 都覆盖了


        return 0;
}

class Tree{};

class Animal {
public:
        virtual void cry() = 0;
};

class Dog : public Animal{
public:
        virtual void cry(){
                cout<<"汪汪"<<endl;

        }
        void doHome(){
                cout<<"看家"<<endl;
        }
};

class Cat : public Animal{
public:
        virtual void cry(){
                cout<<"喵喵"<<endl;
        }

        void doThing(){
                cout<<"抓老鼠"<<endl;
        }
};

void playobj(Animal *base){
        base->cry();//1.继承 2.虚函数重写 3.父类函数指向子类对象 ===>多态
        
        //能识别子类对象
        //dynamic_cast 运行时类型识别
        Dog *pDog = dynamic_cast<Dog *>(base);
        if(pDog  !=  NULL){
                pDog->doHome(); //让狗狗做自己特有的工作
        }

        Cat *pCat = dynamic_cast<Cat *>(base); //父类对象 ===》 子类对象, 向下转型
                                                                                                //把老子 专成 小子
        if(pCat !=  NULL){
                pCat->doThing();  //让猫猫做自己特有的工作
        }
}

int main02(int argc, char const *argv[]){
        Dog d1;
        Cat c1;

        playobj(&d1);
        playobj(&c1);

        Animal *pBase = NULL;
        //pBase = &d1;
        //pBase = static_cast<Animal *>(&d1); //c++编译器在编译的时候进行类型检查
        pBase = reinterpret_cast<Animal *>(&d1);//强制类型转换

        {
                Tree t1;
                //pBase = static_cast<Animal *>(&t1); //c++编译器会做类型检查
                pBase = reinterpret_cast<Animal *>(&t1); //reinterpret_cast 重新解释 ... 强制类型转换的味道
         }

        return 0;
}

//const char *p 的const修饰 让p指向的内存空间 变成只读属性
void printBuf(const char *p){
        //p[0] = 'Z';
        char *p1 = NULL;
        //程序员 要弄清楚的知道 变量:转换之前是什么类型,转换之后是什么类型
        //const char * ====>char * //把只度属性 去掉
        p1 = const_cast<char *>(p);
        p1[0] = 'Z'; //通过p1去修改了内存空间
        cout<<p<<endl;
}

int main(int argc, char const *argv[]){
        char buf[] = "aaaaaaffffddd";

        char *myp = "aaaaaaaaaaaaaffffdd";

        //程序员 要 确保 p所指向的内存空间 确实能修改 ，如果不能修改会带来灾难性后果
        printBuf(buf);

        printBuf(myp);
        return 0;
}
